<?php

namespace app\shop\library\datetime;

class DateHelper
{
    /**
     * 获取最近几天的开始和结束日期
     * @param int $days
     * @return array ['start' => 'xxx', 'end' => 'xxx']
     */
    public static function getStartAndEndDateOfRecentDays(int $days): array
    {
        //开始时间
        $start = date('Y-m-d H:i:s', TimeHelper::beforeDay($days - 1, null, true));

        //结束时间
        $end = date('Y-m-d H:i:s', TimeHelper::afterDay(1, null, true) - 1);

        return [
            'start' => $start,
            'end'   => $end
        ];
    }

    /**
     * 获取最近几天之间的所有日期
     * @param int|string $days
     * @param string     $format
     * @return array
     */
    public function getAllDatesBetweenRecentDays(int|string $days, string $format = 'Y-m-d'): array
    {
        ['start' => $start, 'end' => $end] = self::getStartAndEndDateOfRecentDays($days);

        return self::getAllDateBetweenDates($start, $end, $format);
    }

    /**
     * 获取两个时间之间的所有日期
     * @param        $start
     * @param        $end
     * @param string $format
     * @return array
     */
    public static function getAllDateBetweenDates($start, $end, string $format = 'Y-m-d'): array
    {
        $dates = [];

        if (!TimeHelper::isTimestamp($start)) {
            $start = TimeHelper::toTimestamp($start);
        }
        if (!TimeHelper::isTimestamp($end)) {
            $end = TimeHelper::toTimestamp($end);
        }

        while ($start <= $end) {
            $dates[] = date($format, $start);
            $start   = strtotime('+1 day', $start);
        }

        return $dates;
    }

    /**
     * 获取任意时间所属月份内的开始和结束日期
     * @param int|string|null $timestamp
     * @return array ['start' => 'xxx', 'end' => 'xxx']
     */
    public static function getStartAndEndDateOfMonth(int|string $timestamp = null): array
    {
        if (!$timestamp) {
            $timestamp = time();
        }

        if (!TimeHelper::isTimestamp($timestamp)) {
            $timestamp = TimeHelper::toTimestamp($timestamp);
        }

        $monthStart = strtotime('first day of this month', $timestamp);
        $monthEnd   = strtotime('last day of this month', $timestamp);

        return [
            'start' => $monthStart,
            'end'   => $monthEnd
        ];
    }

    /**
     * 获取任意时间所属月份内的所有日期
     * @param int|string|null $timestamp
     * @param string          $format
     * @return array
     */
    public static function getAllDateBetweenMonth(int|string $timestamp = null, string $format = 'Y-m-d'): array
    {
        list($firstDayOfMonth, $lastDayOfMonth) = self::getStartAndEndDateOfMonth($timestamp);

        return self::getAllDateBetweenDates($firstDayOfMonth, $lastDayOfMonth, $format);
    }

    /**
     * 获取任意时间所属周内的开始和结束日期
     * @param int|string|null $timestamp
     * @return array ['start' => 'xxx', 'end' => 'xxx']
     */
    public static function getStartAndEndDateOfWeek(int|string $timestamp = null): array
    {
        if (!$timestamp) {
            $timestamp = time();
        }
        if (!TimeHelper::isTimestamp($timestamp)) {
            $timestamp = TimeHelper::toTimestamp($timestamp);
        }

        $weekStart = strtotime('last monday', $timestamp);
        $weekEnd   = strtotime('next sunday', $timestamp);

        return [
            'start' => $weekStart,
            'end'   => $weekEnd
        ];
    }

    /**
     *获取任意时间所属周内的所有日期
     * @param int|string|null $timestamp
     * @param string          $format
     * @return array
     */
    public static function getAllDateBetweenWeek(int|string $timestamp = null, string $format = 'Y-m-d'): array
    {
        ['start' => $firstDayOfWeek, 'end' => $lastDayOfWeek] = self::getStartAndEndDateOfWeek($timestamp);

        return self::getAllDateBetweenDates($firstDayOfWeek, $lastDayOfWeek, $format);
    }
}